package org.bp.util;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.bp.event.CollectionMatcher;
import org.bp.struct.Pair;

/**
 * 集合工具类 2018年1月19日下午4:16:10
 * 
 * @author bp
 */
public class CollectionUtils {
	public static Object getObject(Map<String, Object> map, String name) {
		return getObject(map, name, null);
	}

	public static Object getObject(Map<String, Object> map, String name, String defaultValue) {
		if (ObjectUtils.isNull(map)) {
			return null;
		}
		return map.containsKey(name) ? map.get(name) : defaultValue;
	}

	/**
	 * 模仿集合的toString方法将数组转为字符串
	 * 
	 * @param arr
	 * @return
	 */
	public static <T> String toString(T[] arr) {
		if (ObjectUtils.isNull(arr))
			return "null";
		int iMax = arr.length - 1;
		if (iMax == -1)
			return "[]";

		StringBuilder b = new StringBuilder();
		b.append('[');
		for (int i = 0;; i++) {
			b.append(arr[i]);
			if (i == iMax)
				return b.append(']').toString();
			b.append(", ");
		}
	}

	/**
	 * 从字符串中解析出列表，分隔符支持;,: 该方法会将空节点剔除掉
	 *
	 * @param str
	 *            字符串
	 * @return 解析后的列表
	 */
	public static List<String> parseList(String str) {
		final String splitter = "[;,:]";
		return parseList(str, splitter, true);
	}

	public static List<String> parseList(String str, String splitter, boolean trimEmpty) {
		List<String> lst = new ArrayList<String>();
		String[] splits = str.split(splitter, -1);
		for (String item : splits) {
			if (trimEmpty && ObjectUtils.isAbsNull(item))
				continue;
			lst.add(item.trim());
		}

		return lst;
	}

	/**
	 * 从字符串中解析出map key和value之间使用:分割，节点之间使用;分割
	 *
	 * @param str
	 *            原始字符串
	 * @return 解析后的map
	 */
	public static Map<String, String> parseMap(String str) {
		return parseMap(str, ";", ":");
	}

	/**
	 * 从字符串中解析出map 可指定分割符
	 */
	public static Map<String, String> parseMap(String str, String itemSplitter, String kvSplitter) {
		String[] splits = str.split(itemSplitter);
		Map<String, String> map = new HashMap<String, String>();
		for (String item : splits) {
			String[] kvArray = item.split(kvSplitter, 2);
			if (kvArray.length == 1) {
				map.put(kvArray[0], "");
			} else if (kvArray.length >= 2) {
				map.put(kvArray[0].trim(), kvArray[1].trim());
			}
		}
		return map;
	}

	/**
	 * 从字符串中解析出map key和value之间使用:分割，节点之间使用;分割
	 *
	 * @param str
	 *            原始字符串
	 * @return 解析后的map
	 */
	public static Map<String, Integer> parseIntegerMap(String str) {
		String[] splits = str.split("[;,]");
		Map<String, Integer> map = new HashMap<String, Integer>();
		for (String item : splits) {
			String[] kvArray = item.trim().split(":");
			if (kvArray.length != 2)
				continue;

			map.put(kvArray[0].trim(), Integer.valueOf(kvArray[1].trim()));
		}
		return map;
	}

	/**
	 * 将map对象转为字符串，节点之间使用;，key val之间使用:
	 */
	public static String mapToStringWithSemicolon(Map<String, ? extends Object> map) {
		return mapToString(map, ";", ":");
	}

	/**
	 * 将map转换为字符串，分隔符可指定
	 *
	 * @param itemSplitter
	 *            节点之间的字符串
	 * @param kvSplitter
	 *            键值对质检的字符串
	 */
	public static String mapToString(Map<String, ? extends Object> map, String itemSplitter, String kvSplitter) {
		StringBuilder str = new StringBuilder();
		for (Map.Entry<String, ? extends Object> item : map.entrySet()) {
			str.append(item.getKey()).append(kvSplitter).append(item.getValue()).append(itemSplitter);
		}
		if (str.length() > 0)
			str.deleteCharAt(str.length() - 1);
		return str.toString();
	}

	/**
	 * 将map转换为字符串，分隔符可指定
	 *
	 * @param itemSplitter
	 *            节点之间的字符串
	 * @param kvSplitter
	 *            键值对质检的字符串
	 */
	public static String pairListToString(List<Pair<String, ? extends Object>> map, String itemSplitter,
			String kvSplitter) {
		if (ObjectUtils.isNull(map))
			return null;

		StringBuilder str = new StringBuilder();
		for (Pair<String, ?> item : map) {
			str.append(item.getKey()).append(kvSplitter).append(item.getValue().toString()).append(itemSplitter);
		}
		if (str.length() > 0)
			str.deleteCharAt(str.length() - 1);
		return str.toString();
	}

	/**
	 * 筛选符合条件的子列
	 *
	 * @param coll
	 *            列表
	 * @param matcher
	 *            匹配器
	 * @param <T>
	 *            列表节点元素类型
	 * @return 匹配的列表
	 */
	public static <T> List<T> filter(Collection<T> coll, CollectionMatcher<T> matcher) {
		List<T> lst = new ArrayList<T>();
		for (T item : coll) {
			if (matcher.match(item))
				lst.add(item);
		}

		return lst;
	}

	/**
	 * 查找符合条件的节点
	 *
	 * @param collection
	 *            容器
	 * @param matcher
	 *            匹配器
	 * @param <T>
	 *            列表节点元素类型
	 * @return 找到的节点
	 */
	public static <T> T find(Collection<T> collection, CollectionMatcher<T> matcher) {
		for (T item : collection) {
			if (matcher.match(item)) {
				return item;
			}
		}

		return null;
	}

	/**
	 * 按照分页参数取子列表
	 *
	 * @param list
	 *            原始列表
	 * @param pageIndex
	 *            页序
	 * @param pageSize
	 *            页大小
	 */
	public static <T> List<T> subInPage(List<T> list, int pageIndex, int pageSize) throws InvalidParameterException {
		int begin = pageIndex * pageSize;
		int end = (pageIndex + 1) * pageSize;

		if (begin < 0)
			throw new InvalidParameterException("invalid page param");
		if (end < 0)
			throw new InvalidParameterException("invalid page param");

		end = Math.min(list.size(), end);
		begin = Math.max(0, begin);

		if (list.size() > 0 && list.size() > begin) {
			return list.subList(begin, end);
		} else {
			return new ArrayList<T>();
		}
	}

	/**
	 * 将Map转换为Pair
	 */
	public static <K, V> List<Pair<K, V>> mapToPairList(Map<K, V> map) {
		List<Pair<K, V>> list = new ArrayList<Pair<K, V>>();
		for (Map.Entry<K, V> item : map.entrySet()) {
			Pair<K, V> pair = new Pair<K, V>(item.getKey(), item.getValue());
			list.add(pair);
		}
		return list;
	}

	/**
	 * 将List<Map.Entry<String, Integer>>转换为Pair
	 */
	public static <K, V> List<Pair<K, V>> listToPairList(List<Map.Entry<K, V>> list) {
		List<Pair<K, V>> result = new ArrayList<Pair<K, V>>();
		for (Map.Entry<K, V> item : list) {
			Pair<K, V> pair = new Pair<K, V>(item.getKey(), item.getValue());
			result.add(pair);
		}
		return result;
	}

	/**
	 * 根据分页大小，计算总分页数
	 */
	public static int calcPageCount(int size, int pageSize) {
		assert pageSize > 0;

		int count = size / pageSize;
		if (count * pageSize < size) {
			count++;
		}
		return count;
	}

	/**
	 * 将一组节点Wrap到列表中
	 */
	public static <T> List<T> wrapList(@SuppressWarnings("unchecked") T... node) {
		ArrayList<T> list = new ArrayList<T>();
		for (T item : node) {
			list.add(item);
		}
		return list;
	}

	/**
	 * 冒泡排序实现
	 */
	public static <T> void bubbleSort(List<T> list, Comparator<T> comparator) {
		for (int i = 0; i < list.size(); ++i) {
			for (int j = i + 1; j < list.size(); ++j) {
				if (comparator.compare(list.get(i), list.get(j)) > 0) {
					Collections.swap(list, i, j);
				}
			}
		}
	}

	/**
	 * 从列表中随机挑选一个节点返回
	 *
	 * @param list
	 *            List容器
	 * @param <T>
	 *            节点类型
	 * @return 节点值
	 */
	public static <T> T randomSelect(List<T> list) {
		return list.get((int) (Math.random() * list.size()));
	}

	/**
	 * 将list转换成字符串
	 * 
	 * @param list
	 * @param item_split
	 * @return
	 */
	public static <T> String listToString(List<T> list, String item_split) {
		if (ObjectUtils.isNotNull(list)) {
			return null;
		} else {
			StringBuilder str = new StringBuilder();
			Iterator<T> var3 = list.iterator();

			while (var3.hasNext()) {
				Object item = var3.next();
				str.append(item.toString()).append(item_split);
			}

			if (str.length() > 0) {
				str.deleteCharAt(str.length() - 1);
			}

			return str.toString();
		}
	}

	/**
	 * 输出数组
	 * 
	 * @param arr
	 */
	public static <T> void visitArray(T[] arr) {
		System.out.println(toString(arr));
		System.out.println();
		for (T t : arr) {
			System.out.println(t);
		}
	}
}
